#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cstring>
#include "../logic_layer/hash/archivoDirecto.h"

#define _ATTR_DELIM '|'
#define HASHFILE_NAME_ARG_POS 1

string registro;
string loadFileName;
int deleteId = 0;
bool deleteReg = false;
bool truncateFile = false;

//stadisticas
int termCount = 0;
int phraseCount = 0;
std::list<std::string> termsNotFound;
std::list<std::string> termsFound;

typedef struct {
	size_t id;
	std::string phrase;
	std::string surname;
	std::string name;

	bool parseData(std::string &line) {
			std::stringstream ss(line);

			char c;
			if (!(ss >> id && ss >> c && c == _ATTR_DELIM))
				return false;

			if (!getline(ss, phrase, _ATTR_DELIM))
				return false;

			if (!getline(ss, surname, _ATTR_DELIM))
				return false;

			if (!getline(ss, name, _ATTR_DELIM))
				name.clear();

			return true;
		}

	bool parseDataNoID(std::string &line) {
		std::stringstream ss(line);

		if (!getline(ss, name, _ATTR_DELIM))
			return false;

		if (!getline(ss, surname, _ATTR_DELIM))
			return false;

		if (!getline(ss, phrase, _ATTR_DELIM))
			name.clear();

		return true;
	}

} HashRegisterBuffer_t;

void parseArgs(int argc, char* argv[]) {

	for (int i = 2; i < argc; ++i) {
		if (strcmp(argv[i], "-i") == 0) {
			registro.assign(argv[i + 1]);
			i++;
			continue;
		}

		if (strcmp(argv[i], "-d") == 0) {
			deleteReg = true;
			deleteId = atoi(argv[i + 1]);
			i++;
			continue;
		}

		if (strcmp(argv[i], "-l") == 0) {
			loadFileName.assign(argv[i + 1]);
			i++;
			continue;
		}

		if (strcmp(argv[i], "-t") == 0) {
			truncateFile = true;
			continue;
		}
	}
}

void invalid_args() {
	std::cerr << "Argumentos inválidos. " << std::endl
			<< "Uso: app hashFile [-i <csv_reg> | -d <id> | -l <fileName> | -t]"
			<< std::endl;
	exit(1);
}

void loadFile(std::string inputFile, ArchivoDirecto &hash) {

	cerr<<"loading file"<<endl;

	std::ifstream inFile;
	std::string lineBuffer;
	size_t lineNumber = 0;
	inFile.open(inputFile.c_str());
	while (getline(inFile, lineBuffer)) {
		HashRegisterBuffer_t registerData;
		if (lineBuffer.empty()) {
			continue;
		}
		if (!registerData.parseDataNoID(lineBuffer)) {
			std::cerr << "Error al parsear el archivo en la línea: "
					<< lineNumber << std::endl;
			exit(12);
		} else {
			hash.addRecord(lineNumber + 1, registerData.name,
					registerData.surname, registerData.phrase);
		}
		lineNumber++;
	}
}

int main(int argc, char **argv) {

	if (argc < 4)
		invalid_args();

	parseArgs(argc, argv);

	size_t blkSize = 1024 * 4;
	ArchivoDirecto hash(std::string(argv[HASHFILE_NAME_ARG_POS]), blkSize, truncateFile);

	if ( !loadFileName.empty() )
		loadFile(loadFileName, hash);

	if ( !registro.empty() ) {

		cerr<<"adding register"<<endl;
		HashRegisterBuffer_t registerData;

		if (!registerData.parseData(registro)) {
			std::cerr << "Error al parsear el registro a insertar.";
			exit(12);
		} else {
			hash.addRecord(registerData.id, registerData.name,
					registerData.surname, registerData.phrase);
		}
	}

	if (deleteReg == true){
		cerr<<"delete register"<<endl;
		hash.removeRecord(deleteId);
	}


	return 0;
}

